package com.dpteam.service.impl;

import com.dpteam.bean.CheckParam;
import com.dpteam.bean.OrderItemInfo;
import com.dpteam.bean.ProductRecord;
import com.dpteam.bean.UserInfo;
import com.dpteam.dao.*;
import com.dpteam.model.*;
import com.dpteam.service.SaleService;
import com.dpteam.util.Constant;
import com.dpteam.util.TransformUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import com.dpteam.util.MemberLv;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by YangZhi on 2016/1/11.
 */
@Service
@Transactional
public class SaleServiceImpl implements SaleService {

    Logger logger = LoggerFactory.getLogger(SaleServiceImpl.class);

    @Resource
    private ProductDao productDao;

    @Resource
    private OrderDao orderDao;

    @Resource
    private RejectOrderDao rejectOrderDao;

    @Resource
    private RejectReasonDao rejectReasonDao;

    @Resource
    private UserDao userDao;

    @Resource
    private MemberDao memberDao;

    @Resource
    MemberLevelDao memberLevelDao;

    @Override
    public int checkOut(Member member, List<ProductRecord> productList){
        logger.info("checkOut：{},{},{}",member,productList);
        Subject subject = SecurityUtils.getSubject();
        UserInfo userInfo = (UserInfo)subject.getSession().getAttribute(Constant.currentUserKey);
        User cashier = userDao.get(User.class, userInfo.getId());
        Order order = new Order();
        order.setUser(cashier);

        float discount=1;
        if(member!=null){
            order.setMember(member);
            if(member.getMemberLevel()!=null) {
                discount = member.getMemberLevel().getDiscount();
            }
        }

        LocalDateTime ldf = LocalDateTime.now();
        order.setSubmitTime(ldf);

        List<OrderItem> orderItemList = new ArrayList<>();
        OrderItem oi = null;

        float profitTotal = 0,sellPriceTotal=0,buyPriceTotal=0,setPriceTotal=0;

        for(ProductRecord pr : productList){

            Product product = productDao.get(Product.class,pr.getProductId());

            if(product == null)continue;
            if(pr.getProductNum() == 0)continue;

            product.setStorage(product.getStorage()-pr.getProductNum());
            oi = new OrderItem(product,pr.getProductNum(),discount);
            productDao.saveOrUpdate(product);

            orderItemList.add(oi);

            profitTotal += oi.getProfitTotal();
            sellPriceTotal += oi.getSellPriceTotal();
            buyPriceTotal += product.getBuyPrice();
            setPriceTotal += product.getSetPrice();
        }
        order.setProfitTotal(profitTotal);
        order.setSellPriceTotal(sellPriceTotal);
        order.setBuyPriceTotal(buyPriceTotal);
        order.setSetPriceTotal(setPriceTotal);
        order.setOrderItem(orderItemList);
        if(member!=null){
            member.setAllIntegral(member.getAllIntegral()+(int)order.getSellPriceTotal());
            member.setIntegral(member.getIntegral()+(int)order.getSellPriceTotal());
            updateMemberLevel(member);
        }
        return (int)orderDao.save(order);
    }

    @Override
    public int rejectGoods(int orderId, int productId, int productNum, int reasonId) {
        logger.info("rejectGoods:{},{},{},{},",orderId,productId,productNum,reasonId);
        Product product = productDao.get(Product.class, productId);
        Order order = orderDao.get(Order.class, orderId);
        Member member = order.getMember();
        Subject subject = SecurityUtils.getSubject();
        UserInfo userInfo = (UserInfo)subject.getSession().getAttribute(Constant.currentUserKey);
        User cashier = userDao.get(User.class,userInfo.getId());
        if(cashier == null||product == null || order == null||productNum <=0){
            logger.error("rejectGoods:cashier为空或product不存在或order不存在或商品数量不正确！");
            return 0;
        }
        float discount = 1;
        if (member != null) {
            if(member.getMemberLevel()!=null) {
                discount = member.getMemberLevel().getDiscount();
            }
        }
        RejectReason rejectReason = rejectReasonDao.get(RejectReason.class, reasonId);
        if (rejectReason == null) return 0;
        RejectOrder rejectOrder = new RejectOrder();

        rejectOrder.setTime(LocalDateTime.now());
        rejectOrder.setSellPriceTotal(product.getSetPrice() * discount * productNum);
        rejectOrder.setProfitTotal((product.getSetPrice()*discount - product.getBuyPrice())*productNum);
        rejectOrder.setOrder(order);
        rejectOrder.setProduct(product);
        rejectOrder.setAmount(productNum);
        rejectOrder.setUser(cashier);
        rejectOrder.setRejectReason(rejectReason);
        product.setStorage(product.getStorage() + productNum);
        productDao.saveOrUpdate(product);

        if(member!=null){
            member.setAllIntegral(member.getAllIntegral() - (int) rejectOrder.getSellPriceTotal());
            member.setIntegral(member.getIntegral()-(int)rejectOrder.getSellPriceTotal());
            updateMemberLevel(member);
        }
        return (int)rejectOrderDao.save(rejectOrder);
    }

    @Override
    public Member findMemberByPhone(String phone) {
        //TODO 参数校验
        return memberDao.findByPhone(phone);
    }

    @Override
    public boolean preCheck(Member member, List<ProductRecord> productList, CheckParam param) {
        float totalCost = 0.0f;

        for (ProductRecord record : productList) {
            Product product = productDao.get(Product.class, record.getProductId());
            totalCost += product.getSetPrice() * record.getProductNum();
        }
        param.setSetPrice(totalCost);
        float discount = 1.0f;
        if (member == null) {
            param.setSellPrice(totalCost);
            param.setLevel(-1);
            param.setDiscount(discount * 10);
        } else {
            discount = member.getMemberLevel().getDiscount();
            param.setSellPrice(totalCost * discount);
            param.setLevel(member.getMemberLevel().getLevel());
            param.setDiscount(discount * 10);
        }
        return true;
    }

    void updateMemberLevel(Member member){
       if(member.getAllIntegral()<MemberLv.INTEGRAL1){
           member.setMemberLevel(null);
       }else if(member.getAllIntegral()<MemberLv.INTEGRAL2){
           MemberLevel memberLevel = memberLevelDao.get(MemberLevel.class, MemberLv.LEVEL1);
           member.setMemberLevel(memberLevel);
       }else if(member.getAllIntegral()<MemberLv.INTEGRAL3){
           MemberLevel memberLevel = memberLevelDao.get(MemberLevel.class, MemberLv.LEVEL2);
           member.setMemberLevel(memberLevel);
       }else if(member.getAllIntegral()<MemberLv.INTEGRAL4){
           MemberLevel memberLevel = memberLevelDao.get(MemberLevel.class, MemberLv.LEVEL3);
           member.setMemberLevel(memberLevel);
       }else if(member.getAllIntegral()<MemberLv.INTEGRAL5){
           MemberLevel memberLevel = memberLevelDao.get(MemberLevel.class, MemberLv.LEVEL4);
           member.setMemberLevel(memberLevel);
       }else if(member.getAllIntegral()<MemberLv.INTEGRAL6){
           MemberLevel memberLevel = memberLevelDao.get(MemberLevel.class, MemberLv.LEVEL5);
           member.setMemberLevel(memberLevel);
       }else{
           MemberLevel memberLevel = memberLevelDao.get(MemberLevel.class, MemberLv.LEVEL6);
           member.setMemberLevel(memberLevel);
       }
        memberDao.saveOrUpdate(member);
    }

    @Override
    public List<OrderItemInfo> findOrderItem(int orderId) {
        logger.info("通过订单号查询[orderId:{}]", orderId);
        Order order = orderDao.get(Order.class, orderId);
        List<OrderItem> orderItems = order.getOrderItem();
        List<OrderItemInfo> orderItemInfos = new ArrayList<>();
        for (OrderItem orderItem: orderItems) {
            orderItemInfos.add(TransformUtil.fromOrderItem(orderItem));
        }
        return orderItemInfos;
    }

    @Override
    public List<RejectReason> findRejectReasons() {
        return rejectReasonDao.findAllRejectReason();
    }
}
